package com.internetCafes.spms.web.customer.bizservice.customer;

import com.internetCafes.spms.common.utils.ShiroUtils;
import com.internetCafes.spms.common.utils.entity.page.PageItemDTO;
import com.internetCafes.spms.common.utils.entity.page.PageItemVO;
import com.internetCafes.spms.core.exception.RRExceptionCodeEnum;
import com.internetCafes.spms.web.common.model.DataMarkBaseReq;
import com.internetCafes.spms.web.customer.common.cont.CommonConst;
import com.internetCafes.spms.web.customer.common.cont.CustomerConst;
import com.internetCafes.spms.web.customer.common.util.quali.CustomerQualiUtil;
import com.internetCafes.spms.web.customer.entity.area.Area;
import com.internetCafes.spms.web.customer.entity.customer.Customer;
import com.internetCafes.spms.web.customer.model.ExcelImportResultRes;
import com.internetCafes.spms.web.customer.model.FileUploadRes;
import com.internetCafes.spms.web.customer.model.customer.*;
import com.internetCafes.spms.web.customer.model.customer.quali.QualiMatchReq;
import com.internetCafes.spms.web.customer.model.customer.quali.QualiMatchRes;
import com.sms.common.util.hutool.core.bean.BeanUtil;
import com.sms.common.util.hutool.core.collection.CollectionUtil;
import com.sms.common.util.hutool.core.util.ObjectUtil;
import com.sms.common.util.hutool.core.util.StrUtil;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 客户业务接口
 */
public interface IEntCustomerBizService {

    /**
     * 标记
     *
     * @param req 请求
     * @return true/false
     */
    Boolean mark(DataMarkBaseReq req);

    /**
     * 获取企业用户导出的workbook
     *
     * @param req 请求参数
     * @return workbook
     */
    Workbook createCustomerExcel(CustomerExcelReq req);

    /**
     * 客户信息字段验证
     *
     * @param req 请求参数
     * @return true/false
     */
    boolean infoConfirm(CustomerInfoConfirmReq req);


    /**
     * 客户批量保存
     *
     * @param req 请求参数
     * @return 保存结果
     */
    ExcelImportResultRes batchSave(CustomerBatchSaveReq req);

    /**
     * 文件上传接口
     *
     * @param file 文件
     * @return 返回信息
     */
    FileUploadRes fileUpload(MultipartFile file);

    /**
     * 读取excel中的文件
     *
     * @param file 文件
     * @return 导入结果
     */
    List<CustomerPersonImportExcel> personExcelImport(MultipartFile file);

    /**
     * 读取企业excel文件
     *
     * @param file 文件
     * @return 解析结果
     */
    List<CustomerEntImportExcel> entExcelImport(MultipartFile file);

    /**
     * 个人用户excal
     *
     * @param req 请求条件参数
     * @return excel数据
     */
    List<CustomerPersonExcel> customerPersonExcel(CustomerExcelReq req);

    /**
     * 企业客户excel
     *
     * @param req 请求参数
     * @return excel导出数据
     */
    List<CustomerEntExcel> customerEntExcel(CustomerExcelReq req);

    /**
     * 资质匹配内容
     */
    List<QualiMatchRes> qualiMatchList(QualiMatchReq req);

    /**
     * 获取可转让部门人员树
     */
    List<CustomerTransferUserTreeRes> customerTransferUserTree(CustomerTransferUserTreeReq req);

    /**
     * 客户信息统计数据接口
     *
     * @param customerId 客户id
     * @return 统计相关数据
     */
    CustomerCountRes customerCount(Long customerId);

    /**
     * 匹配资质项
     *
     * @param req 请求参数
     * @return 资质列表
     */
    List<QualiMatchRes> qualiMatch(QualiMatchReq req);

    /**
     * 客户转让接口
     *
     * @param req 请求参数
     * @return true/false
     */
    boolean customerTransfer(CustomerTransferReq req);

    /**
     * 取消近期重要客户
     *
     * @param idList 客户id列表
     * @return true/false
     */
    boolean mainlyCancel(List<Long> idList);

    /**
     * 标记为近期重要客户
     *
     * @param idList 客户id列表
     * @return true/false
     */
    boolean mainly(List<Long> idList);

    /**
     * 客户详情信息
     *
     * @param id id
     * @return 客户详情
     */
    CustomerDetailRes customerDetail(Long id);

    /**
     * 客户信息分页
     *
     * @param req 请求参数
     * @return 分页数据
     */
    PageItemVO<CustomerPagingRes> customerPaging(PageItemDTO<CustomerPagingReq> req);

    /**
     * 更新客户信息
     *
     * @param req 请求参数
     * @return true/false
     */
    boolean update(CustomerUpdateReq req);

    /**
     * 客户删除
     *
     * @param idList id列表
     * @return true/false
     */
    boolean delete(List<Long> idList);

    /**
     * 客户信息保存
     *
     * @param req 请求参数
     * @return true/false
     */
    boolean customerSave(CustomerSaveReq req);

    /**
     * 企业客户批量保存
     *
     * @param req      请求参数
     * @param menuName 菜单名称
     * @return 保存结果
     */
    ExcelImportResultRes entBatchSave(CustomerBatchSaveReq req, String menuName);

    /**
     * 个人客户批量保存
     *
     * @param req      请求参数
     * @param menuName 菜单名称
     * @return 保存结果
     */
    ExcelImportResultRes personBatchSave(CustomerBatchSaveReq req, String menuName);

    /**
     * 客户列表中excel重复代码校验
     *
     * @param customerInfoList 客户信息列表
     * @return 重复代码信息
     * @author Zj
     */
    default List<String> repeatExcelCodeList(List<CustomerEntImportExcel> customerInfoList) {
        Map<String, List<CustomerEntImportExcel>> customerListGroupByCertificateCode
                = customerInfoList.stream().collect(Collectors.groupingBy(CustomerEntImportExcel::getCertificateCode));

        List<String> repeatExcelCodeList = new ArrayList<>();

        for (Map.Entry<String, List<CustomerEntImportExcel>> customerListEntry : customerListGroupByCertificateCode.entrySet()) {
            if (customerListEntry.getValue().size() > 1) {
                repeatExcelCodeList.add(customerListEntry.getKey());
            }
        }

        return repeatExcelCodeList;
    }

    /**
     * 企业信息过滤
     *
     * @param customerInfo        客户信息
     * @param res                 批量导入返回结果
     * @param index               下标序号
     * @param typeId              客户类型id
     * @param enterpriseFlag      客户企业标签
     * @param repeatExcelCodeList 数据中重复信用代码列表
     * @param repeatCodeList      数据库中信用代码
     * @param areaGroupByName     区域分组by 区域名称
     * @param qualiMatchMap       资质map
     * @return 客户信息
     * @author Zj
     */
    default Customer entImportExcelFilter(CustomerEntImportExcel customerInfo, ExcelImportResultRes res, int index,
                                          Integer typeId, Integer enterpriseFlag, List<String> repeatExcelCodeList,
                                          List<String> repeatCodeList, Map<String, List<Area>> areaGroupByName,
                                          Map<String, QualiMatchRes> qualiMatchMap) {
        // 必填字段判断
        if (StrUtil.isBlank(customerInfo.getName()) || ObjectUtil.isNull(customerInfo.getCityName())
                || StrUtil.isBlank(customerInfo.getAreaName()) || StrUtil.isBlank(customerInfo.getCertificateCode())
                || StrUtil.isBlank(customerInfo.getQualisContent()) || StrUtil.isBlank(customerInfo.getContactsName())) {
            res.getResultInfoList().add(res.new resultInfo(index, customerInfo.getName(), CommonConst.FlagEnum.NOT.getId(), RRExceptionCodeEnum.PARAM_ERROR.getMessage()));
            return null;
        }
        Customer customerDo = new Customer();
        BeanUtil.copyProperties(customerInfo, customerDo);
        customerDo.setTypeId(typeId).setEnterpriseFlag(enterpriseFlag)
                .setMainlyFlag(CommonConst.FlagEnum.NOT.getId())
                .setThisYearDealFlag(CommonConst.FlagEnum.NOT.getId())
                .setLastYearDealFlag(CommonConst.FlagEnum.NOT.getId())
                .setFollowUserId(ShiroUtils.getUserId());

        if (repeatCodeList.contains(customerInfo.getCertificateCode())) {
            res.getResultInfoList().add(res.new resultInfo(index, customerInfo.getName(), CommonConst.FlagEnum.NOT.getId(), RRExceptionCodeEnum.CUSTOMER_CODE_REPEAT.getMessage()));
            return null;
        }

        if (repeatExcelCodeList.contains(customerInfo.getCertificateCode())) {
            res.getResultInfoList().add(res.new resultInfo(index, customerInfo.getName(), CommonConst.FlagEnum.NOT.getId(), RRExceptionCodeEnum.CUSTOMER_CODE_REPEAT.getMessage()));
            return null;
        }

        if (!areaGroupByName.containsKey(customerInfo.getCityName())
                || !areaGroupByName.containsKey(customerInfo.getAreaName())) {
            res.getResultInfoList().add(res.new resultInfo(index, customerInfo.getName(), CommonConst.FlagEnum.NOT.getId(), RRExceptionCodeEnum.CUSTOMER_AREA_NAME_ERROR.getMessage()));
            return null;
        }
        customerDo.setCityId(CollectionUtil.getFirst(areaGroupByName.get(customerInfo.getCityName())).getId())
                .setAreaId(CollectionUtil.getFirst(areaGroupByName.get(customerInfo.getAreaName())).getId());

        // 资质内容
        List<QualiMatchRes> qualiMatchResList = CustomerQualiUtil.qualiContentMatch(qualiMatchMap, customerInfo.getQualisContent());
        if (CollectionUtil.isNotEmpty(qualiMatchResList)) {
            customerDo.setQualiIdList(qualiMatchResList.stream().map(QualiMatchRes::getId).collect(Collectors.toList()));
        }
        return customerDo;
    }

    /**
     * 个人信息过滤
     *
     * @param customerInfo    客户信息
     * @param res             导出结果数据
     * @param index           下标
     * @param typeId          客户类型id
     * @param enterpriseFlag  是否企业标签
     * @param repeatNameList  重复名称列表
     * @param areaGroupByName 负责区域分组
     * @return 客户信息
     * @author Zj
     */
    default Customer personImportExcelFilter(CustomerEntImportExcel customerInfo, ExcelImportResultRes res, int index,
                                             Integer typeId, Integer enterpriseFlag, List<String> repeatNameList,
                                             Map<String, List<Area>> areaGroupByName) {
        // 必填字段判断
        if (StrUtil.isBlank(customerInfo.getName()) || ObjectUtil.isNull(customerInfo.getCityName())
                || StrUtil.isBlank(customerInfo.getAreaName())) {
            res.getResultInfoList().add(res.new resultInfo(index, customerInfo.getName(), CommonConst.FlagEnum.NOT.getId(), RRExceptionCodeEnum.PARAM_ERROR.getMessage()));
            return null;
        }
        Customer customerDo = new Customer();
        BeanUtil.copyProperties(customerInfo, customerDo);
        customerDo.setTypeId(typeId).setEnterpriseFlag(enterpriseFlag)
                .setContactsName(customerInfo.getName())
                .setMainlyFlag(CommonConst.FlagEnum.NOT.getId())
                .setThisYearDealFlag(CommonConst.FlagEnum.NOT.getId())
                .setLastYearDealFlag(CommonConst.FlagEnum.NOT.getId())
                .setFollowUserId(ShiroUtils.getUserId());

        if (repeatNameList.contains(customerInfo.getName())) {
            res.getResultInfoList().add(res.new resultInfo(index, customerInfo.getName(), CommonConst.FlagEnum.NOT.getId(), RRExceptionCodeEnum.CUSTOMER_PERSON_EXIST.getMessage()));
            return null;
        }

        if (!areaGroupByName.containsKey(customerInfo.getCityName()) || !areaGroupByName.containsKey(customerInfo.getAreaName())) {
            res.getResultInfoList().add(res.new resultInfo(index, customerInfo.getName(), CommonConst.FlagEnum.NOT.getId(), RRExceptionCodeEnum.CUSTOMER_AREA_NAME_ERROR.getMessage()));
            return null;
        }
        customerDo.setCityId(CollectionUtil.getFirst(areaGroupByName.get(customerInfo.getCityName())).getId())
                .setAreaId(CollectionUtil.getFirst(areaGroupByName.get(customerInfo.getAreaName())).getId());

        if (CustomerConst.TypeEnum.DEAL.getId().equals(typeId)) {
            customerDo.setRegularFlag(CommonConst.FlagEnum.IS.getId());
        }
        return customerDo;
    }
}
